home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH6 / SRC / BEZIER2.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-04-01  |  8.4 KB  |  284 lines

  1. VERSION 4.00
  2. Begin VB.Form BezierForm 
  3.    Caption         =   "Bezier Curve"
  4.    ClientHeight    =   5490
  5.    ClientLeft      =   2175
  6.    ClientTop       =   930
  7.    ClientWidth     =   4830
  8.    Height          =   6180
  9.    Left            =   2115
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   366
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   322
  14.    Top             =   300
  15.    Width           =   4950
  16.    Begin VB.CommandButton CmdNew 
  17.       Caption         =   "New"
  18.       Enabled         =   0   'False
  19.       Height          =   375
  20.       Left            =   4320
  21.       TabIndex        =   5
  22.       Top             =   0
  23.       Width           =   495
  24.    End
  25.    Begin VB.CommandButton CmdGo 
  26.       Caption         =   "Go"
  27.       Default         =   -1  'True
  28.       Enabled         =   0   'False
  29.       Height          =   375
  30.       Left            =   3600
  31.       TabIndex        =   4
  32.       Top             =   0
  33.       Width           =   495
  34.    End
  35.    Begin VB.CheckBox ControlCheck 
  36.       Caption         =   "Show Control Points"
  37.       Height          =   255
  38.       Left            =   1080
  39.       TabIndex        =   3
  40.       Top             =   60
  41.       Value           =   1  'Checked
  42.       Width           =   1815
  43.    End
  44.    Begin VB.TextBox DtText 
  45.       Height          =   285
  46.       Left            =   240
  47.       TabIndex        =   2
  48.       Text            =   "0.01"
  49.       Top             =   45
  50.       Width           =   615
  51.    End
  52.    Begin VB.PictureBox Canvas 
  53.       AutoRedraw      =   -1  'True
  54.       Height          =   4815
  55.       Left            =   0
  56.       ScaleHeight     =   317
  57.       ScaleMode       =   3  'Pixel
  58.       ScaleWidth      =   317
  59.       TabIndex        =   0
  60.       Top             =   480
  61.       Width           =   4815
  62.    End
  63.    Begin VB.Label Label1 
  64.       Caption         =   "dt"
  65.       Height          =   255
  66.       Index           =   1
  67.       Left            =   0
  68.       TabIndex        =   1
  69.       Top             =   60
  70.       Width           =   255
  71.    End
  72.    Begin VB.Menu mnuFile 
  73.       Caption         =   "&File"
  74.       Begin VB.Menu mnuFileExit 
  75.          Caption         =   "E&xit"
  76.       End
  77.    End
  78. Attribute VB_Name = "BezierForm"
  79. Attribute VB_Creatable = False
  80. Attribute VB_Exposed = False
  81. Option Explicit
  82. Const PI = 3.14159
  83. Const GAP = 3
  84. ' The endpoints are points 1 and 4. The control
  85. ' points are points 2 and 3.
  86. Dim MaxPt As Integer
  87. Dim PtX() As Single
  88. Dim PtY() As Single
  89. Dim MakingNew As Boolean
  90. ' The index of the point being dragged.
  91. Dim Dragging As Integer
  92. Dim oldmode As Integer
  93. ' ************************************************
  94. ' The blending function for i, N, and t.
  95. ' ************************************************
  96. Function Blend(i As Integer, N As Integer, t As Single) As Single
  97.     Blend = Factorial(N) / Factorial(i) / _
  98.         Factorial(N - i) * t ^ i * (1 - t) ^ (N - i)
  99. End Function
  100. ' ************************************************
  101. ' Draw the curve on the indicated picture box.
  102. ' ************************************************
  103. Sub DrawCurve(pic As PictureBox, start_t As Single, stop_t As Single, dt As Single)
  104. Dim x1 As Single
  105. Dim y1 As Single
  106. Dim t As Single
  107.     x1 = X(start_t)
  108.     y1 = Y(start_t)
  109.     pic.Cls
  110.     pic.CurrentX = x1
  111.     pic.CurrentY = y1
  112.     t = start_t + dt
  113.     Do While t < stop_t
  114.         x1 = X(t)
  115.         y1 = Y(t)
  116.         pic.Line -(x1, y1)
  117.         t = t + dt
  118.     Loop
  119.     x1 = X(stop_t)
  120.     y1 = Y(stop_t)
  121.     pic.Line -(x1, y1)
  122. End Sub
  123. ' ************************************************
  124. ' Return the factorial of a number.
  125. ' ************************************************
  126. Function Factorial(N As Integer) As Long
  127. Dim value As Long
  128. Dim i As Integer
  129.     value = 1
  130.     For i = 2 To N
  131.         value = value * i
  132.     Next i
  133.     Factorial = value
  134. End Function
  135. ' ************************************************
  136. ' The parametric function Y(t).
  137. ' ************************************************
  138. Function Y(t As Single) As Single
  139. Dim i As Integer
  140. Dim value As Single
  141.     For i = 0 To MaxPt
  142.         value = value + PtY(i) * Blend(i, MaxPt, t)
  143.     Next i
  144.     Y = value
  145. End Function
  146. ' ************************************************
  147. ' The parametric function X(t).
  148. ' ************************************************
  149. Function X(t As Single) As Single
  150. Dim i As Integer
  151. Dim value As Single
  152.     For i = 0 To MaxPt
  153.         value = value + PtX(i) * Blend(i, MaxPt, t)
  154.     Next i
  155.     X = value
  156. End Function
  157. ' ************************************************
  158. ' Use DrawCurve to draw the Bezier curve.
  159. ' ************************************************
  160. Private Sub DrawBezier()
  161. Const DOTTED = 2
  162. Dim dt As Single
  163. Dim i As Integer
  164. Dim oldstyle As Integer
  165.     If MaxPt < 0 Then Exit Sub
  166.     dt = CSng(DtText.Text)
  167.     DrawCurve Canvas, 0, 1, dt
  168.     If ControlCheck.value = vbChecked Then
  169.         ' Draw the control points.
  170.         For i = 0 To MaxPt
  171.             Canvas.Line _
  172.                 (PtX(i) - GAP, PtY(i) - GAP)- _
  173.                 Step(2 * GAP, 2 * GAP), , BF
  174.         Next i
  175.         
  176.         ' Connect the control points.
  177.         oldstyle = Canvas.DrawStyle
  178.         Canvas.DrawStyle = DOTTED
  179.         Canvas.CurrentX = PtX(0)
  180.         Canvas.CurrentY = PtY(0)
  181.         For i = 1 To MaxPt
  182.             Canvas.Line -(PtX(i), PtY(i))
  183.         Next i
  184.         Canvas.DrawStyle = oldstyle
  185.     End If
  186. End Sub
  187. ' ************************************************
  188. ' Either collect a new point or select a point and
  189. ' start dragging it.
  190. ' ************************************************
  191. Private Sub Canvas_MouseDown(button As Integer, Shift As Integer, X As Single, Y As Single)
  192. Dim i As Integer
  193.     ' If we are selecting points, do so now.
  194.     If MakingNew Then
  195.         MaxPt = MaxPt + 1
  196.         ReDim Preserve PtX(0 To MaxPt)
  197.         ReDim Preserve PtY(0 To MaxPt)
  198.         PtX(MaxPt) = X
  199.         PtY(MaxPt) = Y
  200.         Canvas.Line _
  201.             (X - GAP, Y - GAP)- _
  202.             Step(2 * GAP, 2 * GAP), , BF
  203.         
  204.         If MaxPt >= 3 Then CmdGo.Enabled = True
  205.         
  206.         Exit Sub
  207.     End If
  208.     ' Otherwise start dragging a point.
  209.     ' Find a close point.
  210.     For i = 0 To MaxPt
  211.         If Abs(PtX(i) - X) <= GAP And _
  212.            Abs(PtY(i) - Y) <= GAP Then Exit For
  213.     Next i
  214.     If i > MaxPt Then Exit Sub
  215.     Dragging = i
  216.     oldmode = Canvas.DrawMode
  217.     Canvas.DrawMode = vbInvert
  218.     PtX(Dragging) = X
  219.     PtY(Dragging) = Y
  220.     Canvas.Line _
  221.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  222.         Step(2 * GAP, 2 * GAP), , BF
  223. End Sub
  224. ' ************************************************
  225. ' Continue dragging a point.
  226. ' ************************************************
  227. Private Sub Canvas_MouseMove(button As Integer, Shift As Integer, X As Single, Y As Single)
  228.     If Dragging < 0 Then Exit Sub
  229.     Canvas.Line _
  230.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  231.         Step(2 * GAP, 2 * GAP), , BF
  232.     PtX(Dragging) = X
  233.     PtY(Dragging) = Y
  234.     Canvas.Line _
  235.         (PtX(Dragging) - GAP, PtY(Dragging) - GAP)- _
  236.         Step(2 * GAP, 2 * GAP), , BF
  237. End Sub
  238. ' ************************************************
  239. ' Finish the drag and redraw the curve.
  240. ' ************************************************
  241. Private Sub Canvas_MouseUp(button As Integer, Shift As Integer, X As Single, Y As Single)
  242.     If Dragging < 0 Then Exit Sub
  243.     Canvas.DrawMode = oldmode
  244.     PtX(Dragging) = X
  245.     PtY(Dragging) = Y
  246.     Dragging = -1
  247.     DrawBezier
  248. End Sub
  249. Private Sub CmdGo_Click()
  250.     MakingNew = False
  251.     CmdNew.Enabled = True
  252.     DrawBezier
  253. End Sub
  254. ' ************************************************
  255. ' Prepare to get new points.
  256. ' ************************************************
  257. Private Sub CmdNew_Click()
  258.     MaxPt = -1
  259.     CmdGo.Enabled = False
  260.     CmdNew.Enabled = False
  261.     MakingNew = True
  262.     Canvas.Cls
  263. End Sub
  264. Private Sub ControlCheck_Click()
  265.     DrawBezier
  266. End Sub
  267. Private Sub Form_Load()
  268.     MakingNew = True
  269.     MaxPt = -1
  270.     Dragging = -1
  271. End Sub
  272. ' ************************************************
  273. ' Make the canvas as big as possible.
  274. ' ************************************************
  275. Private Sub Form_Resize()
  276.     Canvas.Move 0, Canvas.Top, _
  277.         ScaleWidth, ScaleHeight - Canvas.Top
  278.         
  279.     DrawBezier
  280. End Sub
  281. Private Sub mnuFileExit_Click()
  282.     Unload Me
  283. End Sub
  284.